BaseAuthService   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 18
eloc 103
dl 0
loc 135
rs 10
c 0
b 0
f 0

12 Functions

Rating   Name   Duplication   Size   Complexity  
A signInAnonymously 0 3 1
A signOut 0 12 3
A signInViaEmail 0 3 1
A signInByProvider 0 15 2
A signInViaTwitter 0 3 1
A signInViaGoogle 0 3 1
A signInViaGithub 0 3 1
A signInViaFacebook 0 3 1
A signInViaPhone 0 3 1
A setUserInitializedIfNotAlready 0 4 2
A subscribeUserChanges 0 18 3
A updateUserData 0 3 1
1
import { Injectable } from "@angular/core";
2
import { AngularFireAuth } from "@angular/fire/auth";
3
import { ActivatedRoute, Router } from "@angular/router";
4
import { Platform } from "@ionic/angular";
5
import { auth as firebaseAuth, User as FirebaseUser } from "firebase";
6
import { auth } from "firebase/app";
7
import { BehaviorSubject, Observable, Subscription } from "rxjs";
8
import { UniFirebaseLoginConfig } from "../config/uni-firebase-login-config";
9
import { UniFirebaseLoginConfigProvider } from "../config/uni-firebase-login-config-provider";
10
import { UserModel } from "../model/user-model";
11
import { AuthProvider } from "../providers/auth-provider";
12
import { IAuthProvider } from "../providers/i-auth-provider";
13
import { AuthStorageProvider } from "../storage/auth-storage-provider.service";
14
import { IAuthService } from "./i-auth-service";
15
16
@Injectable({
17
  providedIn: "root",
18
})
19
export class BaseAuthService<User extends UserModel = UserModel>
20
  implements IAuthService<User> {
21
  public get user(): User | null {
22
    return this._user.getValue();
23
  }
24
25
  public get user$(): Observable<User | null> {
26
    return this._user;
27
  }
28
29
  public get userInitialized(): boolean {
30
    return this._userInitialized.getValue();
31
  }
32
33
  public get userInitialized$(): Observable<boolean> {
34
    return this._userInitialized;
35
  }
36
37
  public get currentFirebaseUser(): FirebaseUser | null {
38
    return firebaseAuth().currentUser;
39
  }
40
41
  protected config: UniFirebaseLoginConfig;
42
  protected _user: BehaviorSubject<User | null> = new BehaviorSubject<User | null>(
43
    null,
44
  );
45
  protected _userInitialized: BehaviorSubject<boolean> = new BehaviorSubject<
46
    boolean
47
  >(false);
48
  private userDataSubscription: Subscription | undefined;
49
50
  public constructor(
51
    protected router: Router,
52
    protected route: ActivatedRoute,
53
    protected platform: Platform,
54
    protected authProvider: AuthProvider,
55
    protected authStorageProvider: AuthStorageProvider<User>,
56
    protected angularFireAuth: AngularFireAuth,
57
    configProvider: UniFirebaseLoginConfigProvider,
58
  ) {
59
    this.config = configProvider.config;
60
    this.subscribeUserChanges();
61
  }
62
63
  public async signInByProvider(
64
    provider: IAuthProvider,
65
  ): Promise<auth.UserCredential | null> {
66
    const credential = await provider.signIn();
67
    if (
68
      this.config.storage !== false &&
69
      credential &&
70
      credential.user !== null
71
    ) {
72
      await this.authStorageProvider
73
        .getProvider()
74
        .updateStoredDataByFirebaseUser(credential.user);
75
    }
76
    return credential;
77
  }
78
79
  public async signInAnonymously(): Promise<auth.UserCredential | null> {
80
    return this.signInByProvider(this.authProvider.authAnonymous);
81
  }
82
83
  public async signInViaEmail(): Promise<auth.UserCredential | null> {
84
    return this.signInByProvider(this.authProvider.authEmail);
85
  }
86
87
  public async signInViaFacebook(): Promise<auth.UserCredential | null> {
88
    return this.signInByProvider(this.authProvider.authFacebook);
89
  }
90
91
  public async signInViaGithub(): Promise<auth.UserCredential | null> {
92
    return this.signInByProvider(this.authProvider.authGithub);
93
  }
94
95
  public async signInViaGoogle(): Promise<auth.UserCredential | null> {
96
    return this.signInByProvider(this.authProvider.authGoogle);
97
  }
98
99
  public async signInViaPhone(): Promise<auth.UserCredential | null> {
100
    return this.signInByProvider(this.authProvider.authPhone);
101
  }
102
103
  public async signInViaTwitter(): Promise<auth.UserCredential | null> {
104
    return this.signInByProvider(this.authProvider.authTwitter);
105
  }
106
107
  /**
108
   * Handle sign out request
109
   */
110
  public async signOut(): Promise<void> {
111
    const currentUser = auth().currentUser;
112
113
    if (currentUser) {
114
      const providers = this.authProvider.getProvidersByUser(currentUser);
115
116
      for (const provider of providers) {
117
        await provider.signOut();
118
      }
119
    }
120
  }
121
122
  public async updateUserData(user: User) {
123
    await this.authStorageProvider.getProvider().updateStoredDataByUser(user);
124
  }
125
126
  private subscribeUserChanges(): void {
127
    this.angularFireAuth.authState.subscribe((user: any) => {
128
      if (user) {
129
        if (this.userDataSubscription) {
130
          this.userDataSubscription.unsubscribe();
131
        }
132
        this.userDataSubscription = this.authStorageProvider
133
          .getProvider()
134
          .subscribeUserDataFromStorageByFirebaseUser(user)
135
          .subscribe((resultUser: User | null) => {
136
            this._user.next(resultUser);
137
            this.setUserInitializedIfNotAlready();
138
          });
139
      } else {
140
        // Logged out
141
        this._user.next(null);
142
        this.setUserInitializedIfNotAlready();
143
      }
144
    });
145
  }
146
147
  private setUserInitializedIfNotAlready() {
148
    if (!this._userInitialized.getValue()) {
149
      this._userInitialized.next(true);
150
    }
151
  }
152
}
153